package org.example.studentsystem_back.util;


import com.aliyun.oss.ServiceException;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.example.studentsystem_back.domain.Users;
import org.example.studentsystem_back.mapper.UsersMapper;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtUtil {
    @Resource
    private UsersMapper userMapper;

    private static UsersMapper staticUserMapper;
    private static final Long expiration = 1209600L;

    @PostConstruct
    public void init() {
        staticUserMapper = userMapper;
    }

    /**
     * 生成用户token,设置token超时时间
     */
    public static String createToken(String userid,String password) {
        //过期时间
        Date expireDate = new Date(System.currentTimeMillis() + expiration * 1000);
        System.out.println(expireDate);
        Map<String, Object> map = new HashMap<>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        String token = JWT.create()
                // 添加头部
                .withHeader(map)
                //可以将基本信息放到claims中
                //userName
                .withClaim("userid", userid)
                //超时设置,设置过期的日期
                .withExpiresAt(expireDate)
                //签发时间
                .withIssuedAt(new Date())
                //SECRET加密
                .sign(Algorithm.HMAC256(password));     //用password作为sign
        System.out.println(token);
        return token;
    }

    /**
     * 获取当前登录的用户信息
     */
    public static Users getCurrentUser(String token) {
        try{
            if(!StringUtils.isEmpty(token)){
                String userid = JWT.decode(token).getClaim("userid").asString();
                QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("userid", userid);
                return staticUserMapper.selectOne(queryWrapper);
            }
        }catch (Exception e){
            return null;
        }
        return null;
    }


    /**
     * 校验token并解析token
     */
    public static void verifyToken(String token) {
        //获取token中的userId
        String userId;
        try{
            userId = JWT.decode(token).getClaim("userId").asString();   //解码JWT token
        }catch (JWTDecodeException j){
            throw new ServiceException("请登录");
        }

        //用户id去数据库查询用户
        Users user = getCurrentUser(token);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }

        //通过用户密码验证token
        DecodedJWT jwt;
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
            jwt = verifier.verify(token);
            if (jwt.getExpiresAt().before(new Date())) {
                throw new ServiceException("token过期");
            }
        } catch (Exception e) {
            //解码异常则抛出异常
            throw new ServiceException("token解析异常:" + e.getMessage());
        }
    }

}
